iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Mobile Development

從零開始的Swift開發心路歷程2系列 第 28

【從零開始的Swift開發心路歷程2-Day28】doodle jump小遊戲設計(4)我要越跳越高!

  • 分享至 

  • xImage
  •  

昨天讓人物落地時能夠在起跳平台繼續彈跳後,今天就要來設計能讓人物一直往上跳的平台啦!
首先,我們必須先設定人物及平台的位元遮罩

enum bitmasks: UInt32 {
        case player = 0b01 //1
        case platform = 0b10 //2
    }

這邊先來介紹一下categoryBitMask、collisionBitMask及contactTestBitMask吧~

  • categoryBitMask:歸類物理實體所屬類別的位元遮罩
  • collisionBitMask:定義哪些類別的物理實體可以與此物理實體碰撞的位元遮罩
  • contactTestBitMask:定義哪些類別的物理實體可以與此物理實體產生交互通知的位元遮罩
    這樣講可能會太抽象,那我來舉個例子吧!
可以看到上面的enum,player的遮罩是0b01,platform的遮罩是0b10
SpriteKit會將兩個對象的該遮罩進行AND運算,若結果為0就不會發生碰撞及接觸
而0b01和0b10的AND結果為0,因此人物及平台不會發生碰撞

接著,我們先來生成一個平台,並且設定平台的categoryBitMask、collisionBitMask及contactTestBitMask

func makePlatform(){
        let platform = SKSpriteNode(imageNamed: "BrokenLandPiece_Green")
        platform.position = CGPoint(x: GKRandomDistribution(lowestValue: 70, highestValue: 700).nextInt(), y: GKRandomDistribution(lowestValue: 140, highestValue: 300).nextInt() + Int(player.position.y))
        platform.zPosition = 5
        platform.setScale(1)
        platform.physicsBody = SKPhysicsBody(rectangleOf: platform.size)
        platform.physicsBody?.isDynamic = false
        platform.physicsBody?.allowsRotation = false
        platform.physicsBody?.affectedByGravity = false
        platform.physicsBody?.categoryBitMask = bitmasks.platform.rawValue
        platform.physicsBody?.collisionBitMask = 0
        platform.physicsBody?.contactTestBitMask = bitmasks.player.rawValue
        addChild(platform)
    }

為了能讓遊戲順利進行,一開始需要有6個不同高度的平台生成
所以在func didMove加入以下func

makePlatform()
makePlatform2()
makePlatform3()
makePlatform4()
makePlatform5()
makePlatform6()

並且設定人物的物理屬性

player.physicsBody?.isDynamic = false
player.physicsBody?.friction = 0 //摩擦係數
player.physicsBody?.categoryBitMask = bitmasks.player.rawValue
player.physicsBody?.collisionBitMask = 0
player.physicsBody?.contactTestBitMask = bitmasks.platform.rawValue

為什麼我會將人物跟平台的collisionBitMask都設為0呢?
因為假設人物在因為假設人物在平台底下起跳,頭就會撞到平台
所以才將collisionBitMask都設為0
接著,在didBegin內進行人物與平台的接觸判定,當人物接觸到平台後,會被施加一個力並且往上跳躍,被碰觸到的平台會消失,並且再生成兩個平台

func didBegin(_ contact: SKPhysicsContact) {
        let contactA: SKPhysicsBody
        let contactB: SKPhysicsBody
        
        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
            contactA = contact.bodyA //player
            contactB = contact.bodyB //platform
        } else{
            contactA = contact.bodyB//player
            contactB = contact.bodyA //platform
        }
        if contactA.categoryBitMask == bitmasks.player.rawValue && contactB.categoryBitMask == bitmasks.platform.rawValue{
            if player.physicsBody!.velocity.dy < 0{
                player.physicsBody?.velocity = CGVector(dx: player.physicsBody!.velocity.dx, dy: 1400)
                contactB.node?.removeFromParent()
                makePlatform5()
                makePlatform6()
            }
        }
    
    }

如此一來,人物就能一直踩著平台往上跳啦!

但是,一旦人物沒有接觸到平台,就會開始無止境的往下掉,因此,我們明天就來做遊戲結束的判定吧!


上一篇
【從零開始的Swift開發心路歷程2-Day27】doodle jump小遊戲設計(3)拯救人物大作戰!
下一篇
【從零開始的Swift開發心路歷程2-Day29】doodle jump小遊戲設計(5)Game Over!
系列文
從零開始的Swift開發心路歷程230
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言